package com.deloitte.payrollmgtsys.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.SQLException;
import java.sql.Timestamp;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.deloitte.payrollmgtsys.database.Task;
import com.deloitte.payrollmgtsys.database.TaskDAO;

/**
 * A proxy servlet. This servlet proxies all calls to activiti server and performing
 * different local tasks such as saving task completion details to Google Cloud SQL
 * on different calls.
 * 
 * @author muwang
 *
 */
@Controller
public class ProxyServlet {

	@RequestMapping("/proxy")
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		String url = request.getParameter("url");
		String param = request.getParameter("param");
		String method = request.getParameter("method");
		String completeUser = request.getParameter("completeUser");
		String jsonParam = request.getParameter("jsonParam");
		
		String errorServlet = request.getParameter("errorServlet");
		HttpURLConnection connection = null;
		BufferedReader rd = null;
		StringBuilder sb = null;
		String line = null;
		URL serverAddress = null;
		InputStream is = null;
		OutputStream os = null;
		
		param = param + "&access_token=" + request.getSession().getAttribute("access_token");
		
		long validTo = (Long) request.getSession().getAttribute("valid_to");
		
		if (System.currentTimeMillis() > validTo) {
			GoogleUserAuth.getNewToken(request);
		}

		if (param != null) {
			url = url + "?" + param;
		}

		serverAddress = new URL(url);
		
		// Save completed task into database.
		if (completeUser != null) {
			Task task = new Task();
			task.setId(Integer.parseInt(request.getParameter("id")));
			task.setName(request.getParameter("name"));
			task.setProcessID(Integer.parseInt(request.getParameter("processID")));
			task.setAssignee(request.getParameter("assignee"));
			String strCreateTime = request.getParameter("createTime")
					.replace("UTC", "").replace("T", " ");
			Timestamp createTime = Timestamp.valueOf(strCreateTime);
			task.setCreateTime(createTime);
			task.setDescription(request.getParameter("description"));
			String strDueDate = request.getParameter("dueDate")
					.replace("UTC", "").replace("T", " ");
			if (!strDueDate.equals("")) {
				Timestamp dueDate = Timestamp.valueOf(strDueDate);
				task.setDueDate(dueDate);
			}
			task.setCompleteUser(completeUser);
			task.setFormData(request.getParameter("form"));
			TaskDAO taskDAO = new TaskDAO();
			try {
				taskDAO.addTask(task);
			} catch (SQLException e) {
				throw new ServletException(e);
			}
		}

		try {
			connection = (HttpURLConnection) serverAddress.openConnection();
			if (method == null) {
				connection.setRequestMethod("GET");
			} else {
				connection.setRequestMethod(method);
				connection.addRequestProperty("Content-Type", "application/json");
				
			}
			connection.setDoOutput(true);
			connection.setReadTimeout(10000);

			if (jsonParam != null) {
				os = connection.getOutputStream();
				os.write(jsonParam.getBytes());
			}
			
			connection.connect();

			is = connection.getInputStream();
			rd = new BufferedReader(new InputStreamReader(is));
			sb = new StringBuilder();
			while ((line = rd.readLine()) != null) {
				sb.append(line + '\n');
			}
		} finally {
			if (is != null) {
				is.close();
			}
			if (os != null) {
				os.close();
			}
		}

		if (connection.getResponseCode() != HttpServletResponse.SC_OK && errorServlet != null && !errorServlet.equals("")) {
			request.getRequestDispatcher(errorServlet).forward(request, response);
		}
		
		response.setStatus(connection.getResponseCode());
		response.setContentType("text/plain");
		response.getWriter().println(sb);
	}
}
